﻿#include "kpushbutton.h"
#include "themeController.h"
#include "accessinfohelper.h"
#include <QColor>
#include <QPainter>
#include <QStyleOptionButton>
#include <QPainterPath>
#include <QGraphicsDropShadowEffect>
#include <QDebug>
#include <QMenu>
#include <QApplication>
#include <QDesktopWidget>

namespace kdk {
static int margin = 5; //左右边距
static int spacing = 4; //图标文本间距

QStringList iconList{
    "ukui-priority-Low-symbolic",
    "ukui-priority-midding-symbolic",
    "ukui-priority-high-symbolic"
};

class KPushButtonPrivate:public QObject,public ThemeController
{
    Q_DECLARE_PUBLIC(KPushButton)
    Q_OBJECT
public:
    KPushButtonPrivate(KPushButton *parent);

    void changeTheme();

    void updateColor(QStyleOptionButton &option, QColor &backgroundColor, QColor &highlight, QColor &mix, QColor &fontColor);
    void drawBackground(QPainter &painter, QStyleOptionButton &option, QColor &backgroundColor);
    void updateArrowDirection(QPixmap &arrowPixmap, QPoint pos,QPoint desktopPos,QPoint globalPos,QIcon::Mode mode,QIcon::State state);
    void updatePixmap(QPixmap &arrowPixmap,QPixmap &pixmap, QStyleOptionButton &option , QColor &highlight, QColor &fontColor,QIcon::Mode mode,QIcon::State state);
    void drawContent(QPainter &painter,QStyleOptionButton &option,QColor &fontColor,QRect &arrowRect,QRect &textRect,QRect &iconRect,QFontMetrics fm,QPixmap& pixmap,QPixmap &arrowPixmap,uint tf ,QPoint iconPosition,int iconWidth,int iconHeight,int textWidth);

private:
    KPushButton* q_ptr;
    int m_radius;
    int m_bottomLeft;
    int m_topLeft;
    int m_topRight;
    int m_bottomRight;
    QColor m_backgroundColor;
    bool m_useCustomColor;
    bool m_hasOneParam;
    bool m_isTranslucent;
    bool m_isIconHighlight;
    QColor m_iconColor;
    bool m_useCustomIconColor;
    bool m_isBackgroundColorHighlight;
    bool m_isTranslucentFlag;
    bool m_hasArrow;
    KPushButton::ArrowDirection m_arrowDirection;
    KPushButton::ButtonType m_buttonType;
    QGraphicsDropShadowEffect* m_pShadowEffect;
};

KPushButton::KPushButton(QWidget *parent):QPushButton(parent),d_ptr(new KPushButtonPrivate(this))
{
    Q_D(KPushButton);
    d->m_radius = 6;
    d->m_bottomLeft = 6;
    d->m_topLeft = 6;
    d->m_topRight = 6;
    d->m_bottomRight = 6;
    d->m_backgroundColor = palette().color(QPalette::Button);
    d->m_useCustomColor = false;
    d->m_hasOneParam = true;
    d->m_buttonType = NormalType;
    d->m_isTranslucent = false;
    d->m_isIconHighlight = false;
    d->m_iconColor = palette().color(QPalette::ButtonText);
    d->m_useCustomIconColor = false;
    d->m_isBackgroundColorHighlight = false;
    d->m_isTranslucentFlag = false;
    d->m_hasArrow =false;
    d->m_arrowDirection = ArrowBottom;
    connect(d->m_gsetting,&QGSettings::changed, d,&KPushButtonPrivate::changeTheme);
}

KPushButton::~KPushButton()
{

}

void KPushButton::setBorderRadius(int radius)
{
    Q_D(KPushButton);
    d->m_hasOneParam = true;
    d->m_radius = radius;
    update();
}

void KPushButton::setBorderRadius(int bottomLeft,int topLeft,int topRight,int bottomRight)
{
    Q_D(KPushButton);
    d->m_hasOneParam = false;
    d->m_bottomLeft = bottomLeft;
    d->m_topLeft = topLeft;
    d->m_topRight = topRight;
    d->m_bottomRight = bottomRight;
    update();
}

int KPushButton::borderRadius()
{
    Q_D(KPushButton);
    return d->m_radius;
}

void KPushButton::setBackgroundColor(QColor color)
{
    Q_D(KPushButton);
    if(d->m_isBackgroundColorHighlight)
        d->m_isBackgroundColorHighlight = false;
    d->m_useCustomColor = true;
    d->m_backgroundColor = color;
    update();
}

QColor KPushButton::backgroundColor()
{
    Q_D(KPushButton);
    return d->m_backgroundColor;
}

void KPushButton::setButtonType(ButtonType type)
{
    Q_D(KPushButton);
    if(type == KPushButton::ShadowType)
    {
        d->m_pShadowEffect->setOffset(0, 3);
        //阴影颜色
        QColor color(0, 0, 0);
        //阴影半径
        if(ThemeController::themeMode() == LightTheme)
            color.setAlphaF(0.25);
        else
            color.setAlphaF(0.45);
        d->m_pShadowEffect->setColor(color);
        d->m_pShadowEffect->setBlurRadius(8);
        setGraphicsEffect(d->m_pShadowEffect);
    }
    d->m_buttonType = type;
}

KPushButton::ButtonType KPushButton::buttonType()
{
    Q_D(KPushButton);
    return d->m_buttonType;
}

void KPushButton::setTranslucent(bool flag)
{
    Q_D(KPushButton);
    d->m_isTranslucentFlag = flag;
    d->m_isTranslucent = flag;
    d->changeTheme();
}

bool KPushButton::isTranslucent()
{
    Q_D(KPushButton);
    return d->m_isTranslucent;
}

void KPushButton::setIconHighlight(bool flag)
{
    Q_D(KPushButton);
    d->m_isIconHighlight = flag;
}

bool KPushButton::isIconHighlight()
{
    Q_D(KPushButton);
    return d->m_isIconHighlight;
}

void KPushButton::setIconColor(QColor color)
{
    Q_D(KPushButton);
    d->m_useCustomIconColor = true;
    d->m_iconColor = color;
    update();
}

QColor KPushButton::IconColor()
{
    Q_D(KPushButton);
    return d->m_iconColor;
}

void KPushButton::setBackgroundColorHighlight(bool flag)
{
    Q_D(KPushButton);
    if(d->m_useCustomColor)
        d->m_useCustomColor = false;
    d->m_isBackgroundColorHighlight = flag;
}

bool KPushButton::isBackgroundColorHighlight()
{
    Q_D(KPushButton);
    return d->m_isBackgroundColorHighlight;
}

void KPushButton::setArrow(bool flag, KPushButton::ArrowDirection arrowDirection)
{
    Q_D(KPushButton);
    d->m_hasArrow = flag;
    d->m_arrowDirection = arrowDirection;
}


bool KPushButton::hasArrow() const
{
    Q_D(const KPushButton);
    return d->m_hasArrow;
}

bool KPushButton::eventFilter(QObject *watched, QEvent *event)
{
    Q_D(KPushButton);
    return QPushButton::eventFilter(watched,event);
}

void KPushButton::paintEvent(QPaintEvent *event)
{
    Q_D(KPushButton);
    QStyleOptionButton option;
    initStyleOption(&option);

    QPainter painter(this);
    painter.setRenderHint(QPainter::HighQualityAntialiasing);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setRenderHint(QPainter::TextAntialiasing);
    painter.setRenderHint(QPainter::SmoothPixmapTransform);

    QColor fontColor = option.palette.color(QPalette::Active,QPalette::BrightText);
    QColor mix = option.palette.brightText().color();
    QColor highlight = option.palette.highlight().color();
    QColor backgroundColor;

    d->updateColor(option,backgroundColor,highlight,mix,fontColor);
    d->drawBackground(painter,option,backgroundColor);


    /*绘制图标和文字*/
    QPen pen;
    pen.setColor(fontColor);
    painter.setBrush(Qt::NoBrush);
    painter.setPen(pen);
    QPoint point;
    QRect ir = option.rect;
    uint tf = Qt::AlignVCenter;
    QPixmap pixmap;
    QPixmap arrowPixmap ;

    QIcon::Mode mode = option.state & QStyle::State_Enabled ? QIcon::Normal : QIcon::Disabled;
    if (mode == QIcon::Normal && option.state & QStyle::State_HasFocus)
        mode = QIcon::Active;
    QIcon::State state = QIcon::Off;
    if (option.state & QStyle::State_On)
        state = QIcon::On;
    QPoint pos;
    QPoint desktopPos(QApplication::desktop()->availableGeometry().width(),QApplication::desktop()->availableGeometry().height());
    QPoint globalPos;

    d->updateArrowDirection(arrowPixmap,pos,desktopPos,globalPos,mode,state);
    d->updatePixmap(arrowPixmap,pixmap,option,highlight,fontColor,mode,state);

    if (!option.icon.isNull())
    {
        int w = pixmap.width() / pixmap.devicePixelRatio();
        int h = pixmap.height() / pixmap.devicePixelRatio();

        if (!option.text.isEmpty())
            w += option.fontMetrics.boundingRect(option.rect, tf, option.text).width() + 2;

        point = QPoint(ir.x() + ir.width() / 2 - w / 2,
                       ir.y() + ir.height() / 2 - h / 2);

        w = pixmap.width() / pixmap.devicePixelRatio();

        if (option.direction == Qt::RightToLeft)
            point.rx() += w;

        if (option.direction == Qt::RightToLeft)
            ir.translate(-point.x() - 2, 0);
        else
            ir.translate(point.x() + w + 4, 0);

        // left-align text if there is
        if (!option.text.isEmpty())
            tf |= Qt::AlignLeft;
    }
    else
    {
        tf |= Qt::AlignHCenter;
    }

    if(hasArrow())
        point.rx() -= arrowPixmap.width()/2;

    QFontMetrics fm = option.fontMetrics;
    QPoint iconPosition = this->style()->visualPos(option.direction, option.rect, point);
    int iconWidth = option.iconSize.width();
    int iconHeight = option.iconSize.height();
    int textWidth = option.rect.width()-iconWidth*2-iconPosition.x();
    QRect arrowRect;
    QRect textRect;
    QRect iconRect = QRect(iconPosition.x(),iconPosition.y(),iconWidth,iconHeight);

    d->drawContent(painter,option,fontColor,arrowRect,textRect,iconRect,fm,pixmap,arrowPixmap,tf,iconPosition,iconWidth,iconHeight,textWidth);
}

KPushButtonPrivate::KPushButtonPrivate(KPushButton *parent):q_ptr(parent)
{
    Q_Q(KPushButton);
    setParent(parent);
    m_pShadowEffect= new QGraphicsDropShadowEffect(q);

    KDK_OBJ_INFO_FORMAT(m_pShadowEffect);

}

void KPushButtonPrivate::changeTheme()
{
    Q_Q(KPushButton);

    if(m_isTranslucentFlag)
    {
        m_isTranslucent = true;
    }
    else
    {
        m_isTranslucent = false;
    }
    initThemeStyle();
    if(m_buttonType == KPushButton::ShadowType)
    {
        m_pShadowEffect->setOffset(0, 3);
        //阴影颜色
        QColor color(0, 0, 0);
        //阴影半径
        if(ThemeController::themeMode() == LightTheme)
            color.setAlphaF(0.25);
        else
            color.setAlphaF(0.45);
        m_pShadowEffect->setColor(color);
        m_pShadowEffect->setBlurRadius(8);
        q->setGraphicsEffect(m_pShadowEffect);
    }
}

void KPushButtonPrivate::updateColor( QStyleOptionButton &option, QColor &backgroundColor, QColor &highlight, QColor &mix, QColor &fontColor)
{
    Q_Q(KPushButton);
    if(m_buttonType == KPushButton::NormalType || m_buttonType == KPushButton::CircleType || m_buttonType == KPushButton::ShadowType)
    {
        if(m_isTranslucent)
        {
            /*判断使用用户设置的背景色、跟随系统高亮色或是使用默认的背景色*/
            if(m_useCustomColor)
            {
                backgroundColor = m_backgroundColor;
            }else if(m_isBackgroundColorHighlight)
            {
                backgroundColor = highlight;
            }else if(m_buttonType == KPushButton::ShadowType)
            {
                backgroundColor = option.palette.base().color();
            }
            else
            {
                backgroundColor = option.palette.brightText().color();
            }

            if(!option.state.testFlag(QStyle::State_Enabled))
            {
                if(ThemeController::themeMode() == LightTheme)
                {
                    fontColor = option.palette.color(QPalette::Disabled,QPalette::BrightText);
                    backgroundColor.setAlphaF(0.05);
                }
                else
                {
                    fontColor = option.palette.color(QPalette::Disabled,QPalette::BrightText);
                    backgroundColor.setAlphaF(0.1);
                }
            }
            else /*按钮处于可用（Enabled）状态*/
            {
                if(option.state.testFlag(QStyle::State_MouseOver))      /*鼠标在按钮上(hover状态)*/
                {
                    if(m_buttonType == KPushButton::ShadowType)
                    {
                        backgroundColor = option.palette.highlight().color();
                    }
                    if(option.state.testFlag(QStyle::State_Sunken))     /*按钮被选中（clicked）*/
                    {
                        if(m_useCustomColor || m_isBackgroundColorHighlight || m_buttonType == KPushButton::ShadowType)
                            backgroundColor.setAlphaF(0.45);
                        else
                            backgroundColor.setAlphaF(0.21);
                    }
                    else
                    {
                        if(m_useCustomColor || m_isBackgroundColorHighlight)
                            backgroundColor.setAlphaF(0.3);
                        else
                            backgroundColor.setAlphaF(0.16);
                    }
                }
                else
                {
                    if(m_useCustomColor || m_isBackgroundColorHighlight  )
                        backgroundColor.setAlphaF(0.15);
                    else if(m_buttonType == KPushButton::ShadowType)
                    {
                        if(ThemeController::themeMode() == DarkTheme)
                        backgroundColor.setAlphaF(0.2);
                    }
                    else
                        backgroundColor.setAlphaF(0.1);
                }
            }
        }
        else
        {
            /*判断使用用户设置的背景色或是使用默认的背景色*/
            if(m_useCustomColor)
            {
                backgroundColor = m_backgroundColor;
            }else if(m_isBackgroundColorHighlight)
            {
                backgroundColor = highlight;
            }else
            {
                backgroundColor = q->palette().color(QPalette::Button);
            }

            /*按钮处于不可用（Disabled）状态*/
            if(!option.state.testFlag(QStyle::State_Enabled))
            {
                fontColor = option.palette.color(QPalette::Disabled,QPalette::BrightText);
            }
            else
            {
                if(option.state.testFlag(QStyle::State_MouseOver))      /*鼠标在按钮上(hover状态)*/
                {
                    if(ThemeController::themeMode() == LightTheme)
                    {
                        if(option.state.testFlag(QStyle::State_Sunken))     /*按钮被选中（clicked）*/
                        {
                            if(backgroundColor != Qt::transparent)
                                backgroundColor = ThemeController::mixColor(backgroundColor,mix,0.2);
                            else
                                backgroundColor = ThemeController::mixColor(option.palette.button().color(),Qt::black,0.20);
                        }
                        else
                        {
                            if(backgroundColor != Qt::transparent)
                                backgroundColor = ThemeController::mixColor(backgroundColor,mix,0.05);
                            else
                                backgroundColor = ThemeController::mixColor(option.palette.button().color(),Qt::black,0.05);
                        }
                    }
                    else
                    {
                        if(option.state.testFlag(QStyle::State_Sunken))     /*按钮被选中（clicked）*/
                        {
                            if(backgroundColor != Qt::transparent)
                                backgroundColor = ThemeController::mixColor(backgroundColor,mix,0.05);
                            else
                                backgroundColor = ThemeController::mixColor(option.palette.button().color(),Qt::white,0.05);
                        }
                        else
                        {
                            if(backgroundColor != Qt::transparent)
                                backgroundColor = ThemeController::mixColor(backgroundColor,mix,0.2);
                            else
                                backgroundColor = ThemeController::mixColor(option.palette.button().color(),Qt::white,0.15);
                        }
                    }

                }
                if(m_isBackgroundColorHighlight)
                {
                    fontColor = option.palette.color(QPalette::HighlightedText);
                }
                else
                {
//                /*按钮处于可用（Enabled）状态*/
//                    if(option.state.testFlag(QStyle::State_MouseOver))      /*鼠标在按钮上(hover状态)*/
//                    {
//                        if(option.state.testFlag(QStyle::State_Sunken))     /*按钮被选中（clicked）*/
//                            backgroundColor = ThemeController::mixColor(highlight,mix,0.2);
//                        else
//                            backgroundColor = ThemeController::mixColor(highlight,mix,0.05);
                        fontColor = option.palette.color(QPalette::ButtonText);
//                    }
//                    else
//                    {
//                        backgroundColor = q->palette().color(QPalette::Button);
//                    }
                }
            }
        }

        if(q->isChecked())
            backgroundColor = highlight;
    }
}

void KPushButtonPrivate::drawBackground(QPainter &painter, QStyleOptionButton &option, QColor &backgroundColor)
{
    Q_Q(KPushButton);
    /*绘制背景色和rect*/
    painter.save();
    painter.setBrush(backgroundColor);
    QColor borderColor;
    painter.setPen(Qt::NoPen);

    switch(m_buttonType)
    {
    case KPushButton::NormalType:
    {
        if(m_hasOneParam)
        {

                painter.drawRoundedRect(option.rect.adjusted(0,0,0,0),m_radius,m_radius);
        }
        else
        {
            QPainterPath path;

                path.moveTo(option.rect.topLeft() + QPointF(0,m_topLeft));
                path.lineTo(option.rect.bottomLeft() - QPointF(0,m_bottomLeft));
                path.quadTo(option.rect.bottomLeft(),option.rect.bottomLeft() + QPointF(m_bottomLeft,0));
                path.lineTo(option.rect.bottomRight() - QPointF(m_bottomRight,0));
                path.quadTo(option.rect.bottomRight(),option.rect.bottomRight() - QPointF(0,m_bottomRight));
                path.lineTo(option.rect.topRight() + QPointF(0,m_topRight));
                path.quadTo(option.rect.topRight(),option.rect.topRight() - QPointF(m_topRight,0));
                path.lineTo(option.rect.topLeft() + QPointF(m_topLeft,0));
                path.quadTo(option.rect.topLeft(),option.rect.topLeft() + QPointF(0,m_topLeft));

            painter.drawPath(path);
        }
        painter.restore();
        break;
    }
    case KPushButton::CircleType:
        painter.drawRoundedRect(option.rect.adjusted(0,0,0,0),q->width()/2,q->height()/2);
        painter.restore();
        break;
    case KPushButton::ShadowType:
        {
            QColor penColor = Qt::white;
            if(!q->isEnabled())
            {
                if(ThemeController::themeMode() == LightTheme)
                    penColor.setAlphaF(0.05);
                else
                    penColor.setAlphaF(0.1);
            }
            painter.setPen(penColor);
            painter.setBrush(backgroundColor);
            painter.drawEllipse(option.rect.adjusted(0,0,-1,-1));
            painter.restore();
        }
        break;
    default:
        break;
    }
}

void KPushButtonPrivate::updateArrowDirection(QPixmap &arrowPixmap, QPoint pos, QPoint desktopPos, QPoint globalPos, QIcon::Mode mode, QIcon::State state)
{
    Q_Q(KPushButton);
    if(q->hasArrow())
    {
        switch (m_arrowDirection) {
        case KPushButton::ArrowTop:
            arrowPixmap = QIcon::fromTheme("ukui-up-symbolic").pixmap(QSize(16,16), mode, state);
            if(arrowPixmap.devicePixelRatio() != 1)
            {
                arrowPixmap = arrowPixmap.scaled(QSize(16, 16), Qt::KeepAspectRatio, Qt::SmoothTransformation);
            }
            if(q->menu())
            {
                pos.setX(q->rect().left());
                pos.setY(- q->menu()->height());
                globalPos = q->mapToGlobal(pos); //现在
                if(globalPos.x() > (desktopPos.x() - q->menu()->width()))
                    globalPos.setX(desktopPos.x() - q->menu()->width());
                if(globalPos.x() < 0)
                    globalPos.setX(0);
                if(globalPos.y() < 0)
                {
                    pos.setY(q->rect().bottom());
                    globalPos.setY(q->mapToGlobal(pos).y());
                }
                q->menu()->move(globalPos);
            }
            break;
        case KPushButton::ArrowBottom:
            arrowPixmap = QIcon::fromTheme("ukui-down-symbolic").pixmap(QSize(16,16), mode, state);
            if(arrowPixmap.devicePixelRatio() != 1)
            {
                arrowPixmap = arrowPixmap.scaled(QSize(16, 16), Qt::KeepAspectRatio, Qt::SmoothTransformation);
            }
            break;
        case KPushButton::ArrowLeft:
            arrowPixmap = QIcon::fromTheme("ukui-start-symbolic").pixmap(QSize(16,16), mode, state);
            if(arrowPixmap.devicePixelRatio() != 1)
            {
                arrowPixmap = arrowPixmap.scaled(QSize(16, 16), Qt::KeepAspectRatio, Qt::SmoothTransformation);
            }
            if(q->menu())
            {
                pos.setX(q->rect().left() - q->menu()->width());
                pos.setY(q->rect().center().y()/2);
                globalPos = q->mapToGlobal(pos);
                if(globalPos.x() < 0)
                {
                    pos.setY(q->rect().bottom());
                    globalPos.setX(0);
                    globalPos.setY(q->mapToGlobal(pos).y());
                }
                if(globalPos.y() > desktopPos.y() - q->menu()->height())
                {
                    globalPos.setY(desktopPos.y() - q->menu()->height());
                }
                q->menu()->move(globalPos);
            }
            break;
        case KPushButton::ArrowRight:
            arrowPixmap = QIcon::fromTheme("ukui-end-symbolic").pixmap(QSize(16,16), mode, state);
            if(arrowPixmap.devicePixelRatio() != 1)
            {
                arrowPixmap = arrowPixmap.scaled(QSize(16, 16), Qt::KeepAspectRatio, Qt::SmoothTransformation);
            }
            if(q->menu())
            {
                pos.setX(q->rect().right());
                q->menu()->move(q->mapToGlobal(pos));
                globalPos = q->mapToGlobal(pos);
                if(globalPos.x() > (desktopPos.x() - q->menu()->width()))
                {
                    pos.setX(q->rect().left()-q->menu()->width());
                    globalPos.setX(q->mapToGlobal(pos).x());
                }
                if(globalPos.y() > desktopPos.y() - q->menu()->height())
                {
                    globalPos.setY(desktopPos.y() - q->menu()->height());
                }
                q->menu()->move(globalPos);
            }
            break;
        default:
            break;
        }
    }
}

void KPushButtonPrivate::updatePixmap(QPixmap &arrowPixmap, QPixmap &pixmap, QStyleOptionButton &option, QColor &highlight, QColor &fontColor, QIcon::Mode mode, QIcon::State state)
{
    Q_Q(KPushButton);
    pixmap = option.icon.pixmap(option.iconSize, mode, state);
    QColor pixmapColor;
    if(ThemeController::themeMode() == LightTheme)
        pixmapColor = Qt::black;
    else
        pixmapColor = Qt::white;
    if(mode != QIcon::Disabled)
    {
        if(m_isIconHighlight)
        {
            pixmap = ThemeController::drawColoredPixmap(q->icon().pixmap(q->iconSize()),highlight);
            arrowPixmap = ThemeController::drawColoredPixmap(arrowPixmap,pixmapColor);
        }
        else if(m_useCustomIconColor)
        {
            pixmap = ThemeController::drawColoredPixmap(q->icon().pixmap(q->iconSize()),m_iconColor);
            arrowPixmap = ThemeController::drawColoredPixmap(arrowPixmap,pixmapColor);
        }
        else
        {
            if(ThemeController::isPixmapPureColor(pixmap))
            {
                if(!iconList.contains(option.icon.name()))
                    pixmap = ThemeController::drawColoredPixmap(q->icon().pixmap(q->iconSize()),pixmapColor);

            }
            if(ThemeController::isPixmapPureColor(arrowPixmap))
            {
                arrowPixmap = ThemeController::drawColoredPixmap(arrowPixmap,pixmapColor);
            }
        }
    }
    else
    {
        arrowPixmap = ThemeController::drawColoredPixmap(arrowPixmap,q->palette().color(QPalette::Disabled,QPalette::ButtonText));
        pixmap = ThemeController::drawColoredPixmap(pixmap,q->palette().color(QPalette::Disabled,QPalette::ButtonText));
    }
}

void KPushButtonPrivate::drawContent(QPainter &painter, QStyleOptionButton &option, QColor &fontColor, QRect &arrowRect, QRect &textRect, QRect &iconRect, QFontMetrics fm, QPixmap &pixmap, QPixmap &arrowPixmap, uint tf, QPoint iconPosition, int iconWidth, int iconHeight, int textWidth)
{
    Q_Q(KPushButton);
    if(q->hasArrow())
    {
        if(!q->isEnabled())
        {
            qreal opacity = 0.35;
            fontColor.setAlphaF(opacity);
            QPen pen ;
            pen.setColor(fontColor);
            painter.setPen(pen);
            if(option.icon.isNull())
            {
                arrowRect = QRect(option.rect.width() - arrowPixmap.width() - margin,(option.rect.height()- arrowPixmap.width())/2 ,arrowPixmap.width(),arrowPixmap.height());
                textRect = QRect(margin,(option.rect.height()- fm.height())/2 ,option.rect.width()- iconWidth - margin - spacing,fm.height());
                if((fm.width(option.text) > textRect.width()))
                {
                    QString elidedText = fm.elidedText(option.text,Qt::ElideRight,textRect.width());
                    painter.drawText(textRect,tf,elidedText);
                    painter.drawPixmap(arrowRect,arrowPixmap);
                }
                else
                {
                    painter.drawText(textRect,tf,option.text);
                    painter.drawPixmap(arrowRect,arrowPixmap);
                }

            }
            else
            {
                painter.drawPixmap(iconRect,pixmap);
                arrowRect = QRect(option.rect.width() - arrowPixmap.width() - margin,(option.rect.height()- arrowPixmap.width())/2 ,arrowPixmap.width(),arrowPixmap.height());
                textRect = QRect(iconPosition.x() + spacing +iconWidth,0 ,textWidth - margin - spacing,option.rect.height());
                if(fm.width(option.text) > textRect.width())
                {
                    QString elidedText = fm.elidedText(option.text,Qt::ElideRight,textRect.width());
                    painter.drawText(textRect,tf,elidedText);
                    painter.drawPixmap(arrowRect,arrowPixmap);
                }
                else
                {
                    painter.drawText(textRect,tf,option.text);
                    painter.drawPixmap(arrowRect,arrowPixmap);
                }
            }
        }
        else
        {
            if(option.icon.isNull())
            {
                arrowRect = QRect(option.rect.width() - arrowPixmap.width() - margin,(option.rect.height()- arrowPixmap.width())/2,arrowPixmap.width(),arrowPixmap.height());
                textRect = QRect(margin,iconPosition.y() ,option.rect.width()- iconWidth - margin - spacing ,option.rect.height() );
                if(fm.width(option.text) > textRect.width())
                {
                    QString elidedText = fm.elidedText(option.text,Qt::ElideRight,textRect.width());
                    painter.drawText(textRect,tf,elidedText);
                    painter.drawPixmap(arrowRect,arrowPixmap);
                }
                else
                {
                    painter.drawText(textRect,tf,option.text);
                    painter.drawPixmap(arrowRect,arrowPixmap);
                    if(q->toolTip() == option.text)
                        q->setToolTip("");
                }

            }
            else
            {
                arrowRect = QRect(option.rect.width() - arrowPixmap.width() - margin,(option.rect.height()- arrowPixmap.width())/2 ,arrowPixmap.width(),arrowPixmap.height());
                textRect = QRect(iconPosition.x() + spacing +iconWidth,0 ,textWidth - margin - spacing,option.rect.height());
                painter.drawPixmap(iconRect,pixmap);
                if(fm.width(option.text) > textRect.width())
                {
                    QString elidedText = fm.elidedText(option.text,Qt::ElideRight,textRect.width());
                    painter.drawText(textRect,tf,elidedText);
                    painter.drawPixmap(arrowRect,arrowPixmap);
                }
                else
                {
                    painter.drawText(textRect,tf,option.text);
                    painter.drawPixmap(arrowRect,arrowPixmap);
                    if(q->toolTip() == option.text)
                        q->setToolTip("");
                }
            }
        }
    }
    else
    {
        if(!q->isEnabled())
        {
            qreal opacity = 0.35;
            fontColor.setAlphaF(opacity);
            QPen pen ;
            pen.setColor(fontColor);
            painter.setPen(pen);
            if(option.icon.isNull() )
            {
                QString elidedText = fm.elidedText(option.text,Qt::ElideRight,option.rect.width() - 10);
                if(fm.width(option.text) > option.rect.width() - 10)
                {
                    painter.drawText(option.rect.adjusted(margin,0,-margin,0),tf,elidedText);
                    q->setToolTip(option.text);
                }
                else
                {
                    painter.drawText(option.rect.adjusted(margin,0,-margin,0),tf,option.text);
                    if(q->toolTip() == option.text)
                        q->setToolTip("");
                }
            }
            else
            {
                QString elidedText = option.text;
                if(elidedText.isEmpty())
                {
                    iconRect = QRect((q->rect().width() - iconWidth)/2+1,iconPosition.y()-1,iconWidth,iconHeight);
                }
                else
                {
                    if( (fm.width(option.text) > option.rect.width() - margin*2 - spacing - iconWidth))
                    {
                        iconRect = QRect(margin,iconPosition.y(),iconWidth,iconHeight);
                        textRect = QRect(iconRect.right() + spacing,0,option.rect.width() - margin*2 - spacing - iconWidth,option.rect.height());
                        elidedText = fm.elidedText(option.text,Qt::ElideRight,textRect.width());
                        q->setToolTip(option.text);
                    }
                    else
                    {
                        textRect = QRect(iconRect.right() + spacing,0,option.rect.width() - margin*2 - spacing - iconWidth,option.rect.height());
                        if(q->toolTip() == option.text)
                            q->setToolTip("");
                    }
                }
                painter.drawPixmap(iconRect,pixmap);
                painter.drawText(textRect,tf,elidedText);
            }
        }
        else
        {
            if(option.icon.isNull()){
                if(fm.width(option.text) > option.rect.width() - 10)
                {
                    QString elidedText = fm.elidedText(option.text,Qt::ElideRight,option.rect.width() - 10);
                    painter.drawText(option.rect.adjusted(margin,0,-margin,0),tf,elidedText);
                    q->setToolTip(option.text);
                }
                else
                {
                    painter.drawText(option.rect.adjusted(margin,0,-margin,0),tf,option.text);
                    if(q->toolTip() == option.text)
                        q->setToolTip("");
                }
            }
            else
            {
                QString elidedText = option.text;
                if(elidedText.isEmpty())
                {
                    iconRect = QRect((q->rect().width() - iconWidth)/2+1,iconPosition.y(),iconWidth,iconHeight);
                }
                else
                {
                    if( (fm.width(option.text) > option.rect.width() - margin*2 - spacing - iconWidth))
                    {
                        iconRect = QRect(margin,iconPosition.y(),iconWidth,iconHeight);
                        textRect = QRect(iconRect.right() + spacing,0,option.rect.width() - margin*2 - spacing - iconWidth,option.rect.height());
                        elidedText = fm.elidedText(option.text,Qt::ElideRight,textRect.width());
                        q->setToolTip(option.text);
                    }
                    else
                    {
                        textRect = QRect(iconRect.right() + spacing,0,option.rect.width() - margin*2 - spacing - iconWidth,option.rect.height());
                        if(q->toolTip() == option.text)
                            q->setToolTip("");
                    }
                }
                painter.drawPixmap(iconRect,pixmap);
                painter.drawText(textRect,tf,elidedText);
            }
        }
    }
}

}
#include "kpushbutton.moc"
#include "moc_kpushbutton.cpp"
